package util

import (
	"fmt"
	"time"
)

const PERIOD_DIFF = 5 //用于ResultID生成，版本迁移过渡时用5，版本稳定时用1

func GetDuration(buyDate, sellDate DateAndTime) float64 {
	buydate, _ := time.ParseInLocation("20060102", fmt.Sprintf("%v", buyDate), time.Local)
	selldate, _ := time.ParseInLocation("20060102", fmt.Sprintf("%v", sellDate), time.Local)
	return selldate.Sub(buydate).Hours() / 24
}

//generate subaccount id
func GeneratorSubAccID(userid UserID, period Period) AccountID {
	return AccountID(userid)<<32 + AccountID(period)
}

//generate result id
func GeneratorResultID(d, t DateAndTime, p Period) ResultID {
	date := ResultID(d) * 100000
	time := ResultID(t / 100)
	time = (time/100*60 + time%100) * 10
	period := ResultID(p) + PERIOD_DIFF
	return (period + date + time) * 1000000
}

//generate timestamp
func GeneratorTimestamp(d, t DateAndTime) TimeStamp {
	return TimeStamp(d)*1000000 + TimeStamp(t)
}

//数据库中level的值为1~4，程序中定义的对应值为0~3
func ConvertLevel(l Level) (Level, error) {
	if l > 0 && l <= 4 {
		return l - 1, nil
	}
	if l == 0 {
		return l, nil
	}
	return l, fmt.Errorf("Unknown level value(0~4): %v!", l)
}

//数据库中level的值为1~4，程序中定义的对应值为0~3
func ConvertLevel_TPS(l Level) (Level, error) {
	if l > 0 && l <= 4 {
		return l - 1, nil
	}
	return l, fmt.Errorf("Unknown level value(1~4): %v!", l)
}

func ConvertLevelForStockPool(l Level) (Level, error) {
	if l > 0 && l <= 4 {
		return l - 1, nil
	}
	if l == 0 {
		return l, nil
	}
	return l, fmt.Errorf("Unknown level value(1~4): %v!", l)
}

func GetTime() DateAndTime {
	hour, minute, second := time.Now().Clock()
	return DateAndTime(hour*10000 + minute*100 + second)
}

//获取今日日期
func Today() DateAndTime {
	d := time.Now()
	return DateAndTime(d.Year()*10000 + int(d.Month())*100 + d.Day())
}

func Max(a, b int64) int64 {
	if a >= b {
		return a
	}
	return b
}

func Min(a, b int64) int64 {
	if a >= b {
		return b
	}
	return a
}

func FMax(a, b float64) float64 {
	if a >= b {
		return a
	}
	return b
}

func FMin(a, b float64) float64 {
	if a >= b {
		return b
	}
	return a
}

//选择使用的打法类型
func GetMethodType(accversion ACCVERSION) MethodType {
	switch accversion {
	case ACCVERSION_1:
		return MethodType_1
	case ACCVERSION_2, ACCVERSION_3:
		return MethodType_2
	case ACCVERSION_4:
		return MethodType_3
	}
	return MethodType_3
}

//选择使用的打法类型
func GetMethodType_New(methodtype uint8, methodstyle MethodStyle) (MethodType, MethodStyle) {
	if methodtype == 0 {
		return 0, MethodStyle_AllIn
	}
	if methodtype > 0 && methodtype < 4 {
		return MethodType(methodtype - 1), methodstyle
	}
	return 0, methodstyle
}

func GetDifferentStockCount(accversion ACCVERSION) int {
	switch accversion {
	case ACCVERSION_1:
		return DIFFERENT_STOCK_COUNT_2PERIOD
	case ACCVERSION_2:
		return DIFFERENT_STOCK_COUNT_3PERIOD
	case ACCVERSION_3, ACCVERSION_4:
		return DIFFERENT_STOCK_COUNT_4PERIOD
	}
	return DIFFERENT_STOCK_COUNT_4PERIOD
}
